home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_08 / phillip2 / ht.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-18  |  15.9 KB  |  603 lines

  1.  
  2.  
  3.    /**************************************************
  4.    *
  5.    *   file d:\cips\ht.c
  6.    *
  7.    *   Functions: This file contains
  8.    *       display_using_halftoning
  9.    *       half_tone
  10.    *       show_half_tone
  11.    *       get_threshold_value
  12.    *
  13.    *   Purpose: This program displays an image using 
  14.    *      a halftoning process.  The algorithm was 
  15.    *      taken from "Personal computer based image 
  16.    *      processing with halftoning," John A Saghri, 
  17.    *      Hsieh S. Hou, Andrew Tescher, Optical 
  18.    *      Engineering, March 1986, Vol.25, No. 3, 
  19.    *      pp 499-503. The display_using_halftoning
  20.    *      determines display size and reads the image.
  21.    *      The half_tone function implements the 
  22.    *      algorithm shown on page 502 of the article.
  23.    *
  24.    *      The function print_halftone_array prints 
  25.    *      a half toned image array to a regular line 
  26.    *      printer.
  27.    *
  28.    *
  29.    *   External Calls:
  30.    *      rtiff.c - read_tiff_image
  31.    *      numcvrt.c - get_integer
  32.    *
  33.    *   Modifications:
  34.    *      30 September 86 - created
  35.    *      18 August 1990 - modified for use in the
  36.    *          C Image Processing System.
  37.    *
  38.    *
  39.    **************************************************/
  40.  
  41.  
  42. #include "cips.h"
  43.  
  44. #define  FORMFEED  '\014'
  45.  
  46. float eg[ROWS][COLS], ep[ROWS][COLS];
  47.  
  48. display_using_halftoning(in_image, file_name,
  49.          il, ie, ll, le, threshold, invert,
  50.          image_colors, image_header, monitor_type,
  51.          print, show_hist, color_transform)
  52.  
  53.    char  color_transform[], file_name[], 
  54.          monitor_type[];
  55.    int   image_colors, invert,
  56.          il, ie, ll, le, threshold,
  57.          print, show_hist;
  58.    short in_image[ROWS][COLS];
  59.    struct tiff_header_struct *image_header;
  60.  
  61. {
  62.    char response[80];
  63.  
  64.    int  a,
  65.         b,
  66.         channel,
  67.         color,
  68.         count,
  69.         data_color,
  70.         display_mode,
  71.         horizontal,
  72.         i,
  73.         j,
  74.         k,
  75.         l,
  76.         line_color,
  77.         max_horizontal,
  78.         max_vertical,
  79.         not_finished,
  80.         one,
  81.         vertical,
  82.         x,
  83.         x_offset,
  84.         y,
  85.         y_offset,
  86.         zero;
  87.  
  88.    float area, new_grays;
  89.  
  90.    unsigned long histogram[256], new_hist[256];
  91.  
  92.  
  93.        if(  (show_hist == 1)  &&
  94.             (color_transform[0] != 'H'))
  95.           zero_histogram(histogram);
  96.  
  97.          /*******************************************
  98.          *
  99.          *   Use the monitor type to set the vertical
  100.          *   horizontal and display_mode parameters.
  101.          *   Also set the values for one and zero.
  102.          *   one and zero will vary depending on the
  103.          *   monitor type.
  104.          *
  105.          ********************************************/
  106.  
  107.  
  108.       if(  (monitor_type[0] == 'M')  ||
  109.            (monitor_type[0] == 'm')){
  110.          vertical     = 3;
  111.          horizontal   = 2;
  112.          display_mode = HRESBW;
  113.          one          = 1;
  114.          zero         = 0;
  115.       }
  116.  
  117.       if(  (monitor_type[0] == 'C')  ||
  118.            (monitor_type[0] == 'c')){
  119.          vertical     = 3;
  120.          horizontal   = 2;
  121.          display_mode = MRES4COLOR;
  122.          one          = 3;
  123.          zero         = 1;
  124.       }
  125.  
  126.       if(  (monitor_type[0] == 'V')  ||
  127.            (monitor_type[0] == 'v')){
  128.          vertical     = 6;
  129.          horizontal   = 4;
  130.          display_mode = VRES16COLOR;
  131.          one          = 5;
  132.          zero         = 1;
  133.       }
  134.  
  135.       if(  (monitor_type[0] == 'E')  ||
  136.            (monitor_type[0] == 'e')){
  137.          vertical     = 6;
  138.          horizontal   = 3;
  139.          display_mode = ERESCOLOR;
  140.          one          = 5;
  141.          zero         = 1;
  142.       }
  143.  
  144.       max_horizontal = (image_header->image_length+50)
  145.                          /COLS;
  146.       max_vertical   = (image_header->image_width+50)
  147.                          /ROWS;
  148.  
  149.       if(horizontal > max_horizontal) 
  150.             horizontal = max_horizontal;
  151.       if(vertical > max_vertical) 
  152.             vertical = max_vertical;
  153.  
  154.       if(print == 1){
  155.          vertical   = 1;
  156.          horizontal = 1;
  157.       }
  158.  
  159.  
  160.  
  161.         /****************************************
  162.         *
  163.         *   If color transform wants histogram
  164.         *   equalization, then read in the
  165.         *   image arrays and calculate the
  166.         *   histogram.   Zero both the histogram
  167.         *   and the new_hist.  You will need the
  168.         *   new_hist if you want to display the
  169.         *   equalized hist.
  170.         *
  171.         *****************************************/
  172.  
  173.       if(color_transform[0] == 'H'){
  174.          count = 1;
  175.          zero_histogram(histogram);
  176.          zero_histogram(new_hist);
  177.          for(a=0; a<vertical; a++){
  178.             for(b=0; b<horizontal; b++){
  179.  
  180.                x = a*COLS;
  181.                y = b*ROWS;
  182.  
  183.                printf("\nHT> Calculating histogram");
  184.                printf(" %d of %d",
  185.                       count,vertical*horizontal);
  186.                count++;
  187.  
  188.                read_tiff_image(file_name, in_image, 
  189.                             il+y, ie+x, ll+y, le+x);
  190.                calculate_histogram(in_image, 
  191.                                    histogram);
  192.  
  193.             }  /* ends loop over b */
  194.          }  /* ends loop over a */
  195.       }  /* ends if display_mode == H */
  196.  
  197.  
  198.  
  199.  
  200.            /* set graphics mode */
  201.       if(print == 0)
  202.          my_setvideomode(display_mode); /* MSC 6.0 */
  203.       else{
  204.          printf("\n\nHT> Calculating for printing ");
  205.          printf("\nHT> Counting from 0 to 99\n");
  206.       }
  207.  
  208.         /********************************************
  209.         *
  210.         *   Loop over horizontal and vertical. Read
  211.         *   the image array and display it after
  212.         *   calculating the half tone values.
  213.         *
  214.         *
  215.         *   If you want to show the histogram AND
  216.         *   do not want to do hist equalization
  217.         *   then calculate the hist from the
  218.         *   original image array.
  219.         *
  220.         *   If you want to do hist equalization
  221.         *   then calculate the new_hist AFTER
  222.         *   the image has been equalized.
  223.         *
  224.         *   We will equalize the histogram down
  225.         *   to half the original shades of gray
  226.         *   and will cut the threshold in half.
  227.         *
  228.         *****************************************/
  229.  
  230.  
  231.  
  232.       for(i=0; i<horizontal; i++){
  233.          for(j=0; j<vertical; j++){
  234.             read_tiff_image(file_name, in_image, 
  235.                            il+i*ROWS, ie+j*COLS, 
  236.                            ll+i*ROWS, le+j*COLS);
  237.  
  238.             if(   (show_hist == 1)  &&
  239.                   (color_transform[0] != 'H'))
  240.                calculate_histogram(in_image, histogram);
  241.  
  242.             if(color_transform[0] == 'H'){
  243.  
  244.                area = ((long)(vertical))*
  245.                       ((long)(horizontal));
  246.                area = area*10000.0;
  247.                new_grays = image_colors/2;
  248.  
  249.                perform_histogram_equalization(in_image,
  250.                         histogram, new_grays, area);
  251.  
  252.                calculate_histogram(in_image, new_hist);
  253.  
  254.             }  /* ends if color_transform == S */
  255.  
  256.             if(color_transform[0] == 'H')
  257.                half_tone(in_image, threshold/2, 
  258.                       eg, ep, i, j,
  259.                       one, zero, invert, print);
  260.  
  261.             else
  262.                half_tone(in_image, threshold, 
  263.                       eg, ep, i, j,
  264.                       one, zero, invert, print);
  265.  
  266.          }  /* ends loop over j */
  267.       }  /*  ends loop over i */
  268.  
  269.  
  270.  
  271.          /***************************
  272.          *
  273.          *   if show_hist == 1 then
  274.          *   display the histogram
  275.          *   in the lower right hand
  276.          *   corner of screen
  277.          *
  278.          ****************************/
  279.  
  280.       if(  (show_hist == 1)   &&
  281.            (print == 0)){
  282.  
  283.          if(monitor_type[0] == 'V'){
  284.             y_offset   = 470;
  285.             x_offset   = 380;
  286.             line_color = 3;
  287.             data_color = 8;
  288.          }
  289.  
  290.          if(monitor_type[0] == 'E'){
  291.             y_offset   = 310;
  292.             x_offset   = 380;
  293.             line_color = 3;
  294.             data_color = 8;
  295.          }
  296.  
  297.          if(monitor_type[0] == 'M'){
  298.             y_offset   = 190;
  299.             x_offset   = 60;
  300.             line_color = 1;
  301.             data_color = 1;
  302.          }
  303.  
  304.          if(monitor_type[0] == 'C'){
  305.             y_offset   = 190;
  306.             x_offset   = 60;
  307.             line_color = 1;
  308.             data_color = 3;
  309.          }
  310.  
  311.          if(color_transform[0] == 'S')
  312.             display_histogram(histogram, x_offset,
  313.                    y_offset, line_color, data_color);
  314.  
  315.          if(color_transform[0] == 'H')
  316.             display_histogram(new_hist, x_offset,
  317.                    y_offset, line_color, data_color);
  318.  
  319.       }  /* ends if show_hist == 1 and print == 0 */
  320.  
  321.  
  322.  
  323.       if(print == 1) 
  324.          printf("\n\nHT> Hit ENTER to continue");
  325.       gets(response);
  326.       my_clear_text_screen();
  327.  
  328. }  /* ends main  */
  329.  
  330.  
  331.  
  332.  
  333.  
  334.        /*********************************************
  335.        *
  336.        *   half_tone(...
  337.        *
  338.        *   ep[m][n] = sum of erros propogated
  339.        *               to position (m,n).
  340.        *   eg[m][n] = total error generated at
  341.        *               location (m,n).
  342.        *
  343.        **********************************************/
  344.  
  345. half_tone(in_image, threshold, eg, ep, yoff,
  346.            xoff, one, zero, invert, print)
  347.    int   invert, threshold, xoff, yoff,
  348.          one, print, zero;
  349.    float eg[ROWS][COLS], ep[ROWS][COLS];
  350.    short in_image[ROWS][COLS];
  351. {
  352.    float c[2][3],
  353.          sum_p,
  354.          t,
  355.          tt;
  356.    int   color, count, i, j, m, n;
  357.    short srow, scol;
  358.  
  359.    c[0][0] = 0.0;
  360.    c[0][1] = 0.2;
  361.    c[0][2] = 0.0;
  362.    c[1][0] = 0.6;
  363.    c[1][1] = 0.1;
  364.    c[1][2] = 0.1;
  365.    count   =   0;
  366.  
  367.       /***********************************************
  368.       *
  369.       *   Calculate the total propogated error
  370.       *   at location(m,n) due to prior
  371.       *   assignment.
  372.       *
  373.       *   Go through the input image.  If the output
  374.       *   should be one then display that pixel as such.
  375.       *   If the output should be zero then display it
  376.       *   that way.
  377.       *
  378.       *   Also set the pixels in the input image array
  379.       *   to 1's and 0's in case the print option
  380.       *   was chosen.
  381.       *
  382.       ************************************************/
  383.  
  384.    for(i=0; i<ROWS; i++){
  385.       for(j=0; j<COLS; j++){
  386.          eg[i][j] = 0.0;
  387.          ep[i][j] = 0.0;
  388.       }
  389.    }
  390.  
  391.        /**********************************************
  392.        *
  393.        *   29 February 1988 - Fix to remove a solid 
  394.        *   line at the bottom of each region. Loop 
  395.        *   over ROWS-1 and then draw an extra line.
  396.        *
  397.        **********************************************/
  398.  
  399.    for(m=0; m<ROWS-1; m++){
  400.       for(n=0; n<COLS; n++){
  401.  
  402.          sum_p = 0.0;
  403.          for(i=0; i<2; i++){
  404.             for(j=0; j<3; j++){
  405.                sum_p = sum_p + 
  406.                        c[i][j] * eg[m-i+1][n-j+1];
  407.             }  /* ends loop over j */
  408.          }     /* ends loop over i */
  409.  
  410.          ep[m][n] = sum_p;
  411.          t = in_image[m][n] + ep[m][n];
  412.          tt = t;
  413.  
  414.                /**********************************
  415.                *
  416.                *    Here set the point [m][n]=one
  417.                *
  418.                ***********************************/
  419.  
  420.          if(t > threshold){
  421.             eg[m][n] = t - threshold*2;
  422.             ++count;
  423.             color = one;
  424.             if(invert == 1) color = zero;
  425.  
  426.             scol = (short)(n + xoff*COLS);
  427.             srow = (short)(m + yoff*ROWS);
  428.  
  429.             if(invert == 1)
  430.                in_image[m][n] = 1;
  431.             else
  432.                in_image[m][n] = 0;
  433.  
  434.             if(print == 0){
  435.                my_setcolor(color);      /* MSC 6.0 */
  436.                my_setpixel(scol, srow); /* MSC 6.0 */
  437.             }  /* ends if print == 0 */
  438.          }  /* ends if t > threshold  */
  439.  
  440.  
  441.                /**********************************
  442.                *
  443.                *    Here set the point [m][n]=zero
  444.                *
  445.                ***********************************/
  446.  
  447.          else{
  448.             eg[m][n] = t;
  449.             color = zero;
  450.             if(invert == 1) color = one;
  451.  
  452.             scol = (short)(n + xoff*COLS);
  453.             srow = (short)(m + yoff*ROWS);
  454.  
  455.             if(invert == 1)
  456.                in_image[m][n] = 0;
  457.             else
  458.                in_image[m][n] = 1;
  459.  
  460.             if(print == 0){
  461.                my_setcolor(color);      /* MSC 6.0 */
  462.                my_setpixel(scol, srow); /* MSC 6.0 */
  463.             } /* ends if print == 0 */
  464.  
  465.          }  /* ends else t <= threshold  */
  466.  
  467.       }  /* ends loop over n columns */
  468.  
  469.       if(print == 1) printf("%3d", m);
  470.  
  471.    }         /* ends loop over m rows */
  472.  
  473.  
  474.       /* Now display an extra line if print is 0 */
  475.    if(print == 0){
  476.       for(j=0; j<COLS; j++){
  477.  
  478.         if(in_image[ROWS-2][j] == 1)
  479.            color = zero;
  480.         else
  481.            color = one;
  482.  
  483.         if(invert == 1){
  484.             if(in_image[ROWS-2][j] == 1)
  485.                color = zero;
  486.             else
  487.                color = one;
  488.         }  /* ends if invert == 1 */
  489.  
  490.         scol = (short)(j + xoff*COLS);
  491.         srow = (short)(ROWS-1 + yoff*ROWS);
  492.         my_setcolor(color);      /* MSC 6.0 */
  493.         my_setpixel(scol, srow); /* MSC 6.0 */
  494.  
  495.       }        /* ends loop over j */
  496.    }        /* ends if print == 0 */
  497.  
  498.  
  499.    if(print == 1) print_halftone_array(in_image);
  500.  
  501. }  /*  ends half_tone  */
  502.  
  503.  
  504.  
  505.  
  506.  
  507.    /*******************************
  508.    *
  509.    *   get_threshold_value(...
  510.    *
  511.    ********************************/
  512.  
  513. get_threshold_value(threshold, print)
  514.    int *print, *threshold;
  515. {
  516.    int i;
  517.    printf("\nHT> The threshold = %d", *threshold);
  518.    printf("\nHT> Enter new theshold value ");
  519.    printf("(0 for no change) \n___\b\b\b");
  520.    get_integer(&i);
  521.    if((i != 0) && (i!= *threshold))
  522.       *threshold = i;
  523.  
  524.    printf(
  525.       "\nHT> print = %d (1 for print  0 for display)", 
  526.       *print);
  527.    printf("\nHT> Enter print value  \n_\b");
  528.    get_integer(&i);
  529.    *print = i;
  530. }
  531.  
  532.  
  533.  
  534.  
  535.    /********************************************
  536.    *
  537.    *   print_halftone_array(...
  538.    *
  539.    *   This function takes the halftoned images
  540.    *   and prints it to a line printer.  If the
  541.    *   image array has a 1 then print a ' '.
  542.    *   If the image array has a 0 then print
  543.    *   a '*'.
  544.    *
  545.    *********************************************/
  546.  
  547.  
  548. print_halftone_array(image)
  549.    short image[ROWS][COLS];
  550. {
  551.    char printer_name[80], response[80], string[101];
  552.    FILE *printer;
  553.    int        i, j, l, line_counter;
  554.  
  555.    line_counter = 0;
  556.  
  557.    strcpy(printer_name, "prn");
  558.  
  559.    if( (printer = fopen(printer_name, "w")) == NULL)
  560.       printf("\nHT> Could not open printer");
  561.    else{
  562.       printf("\nOpened printer and now printing");
  563.  
  564.     /*************************************************
  565.     *
  566.     *   Loop over the rows in the image.  For each row
  567.     *   first clear out the string print buffer.
  568.     *   Then go through the columns and set the string
  569.     *   to either '*' or ' '.  Finally, write the
  570.     *   string out to the printer.
  571.     *
  572.     *************************************************/
  573.  
  574.    for(i=0; i<ROWS; i++){
  575.  
  576.       for(l=0; l<COLS+1; l++) string[l] = '\0';
  577.  
  578.       for(j=0; j<COLS; j++){
  579.          if(image[i][j] == 1)
  580.             string[j] = '*';
  581.          else
  582.             string[j] = ' ';
  583.       }  /* ends loop over j columns */
  584.  
  585.       printf("%3d", i);
  586.       fputs(string, printer);
  587.       fputc('\n', printer);
  588.       line_counter = line_counter + 1;
  589.       if(line_counter >= 53){
  590.          line_counter = 0;
  591.          putc(FORMFEED, printer);
  592.       }  /* ends if line_counter >=53  */
  593.  
  594.    }  /* ends loop over i rows */
  595.  
  596.  
  597.    }  /* ends opened printer */
  598.  
  599.    putc(FORMFEED, printer);
  600.    fclose(printer);
  601.  
  602. }  /* ends print_halftone_array */
  603.